home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / falcon / nt_dsp1.lzh / NT_DSP1.MSA / AUDIO / RVB2.ASM < prev   
Encoding:
Assembly Source File  |  1990-01-17  |  15.5 KB  |  417 lines

  1. ;   filename: RVB2.ASM
  2. ;
  3. ;
  4. ;    This code is an optimized version of the reverberation algorithm
  5. ;    found in file RVB1.ASM.  This program makes use of the parallel
  6. ;    move functionality of the 56001.  While this tends to make the
  7. ;    code less readible, it does increase its speed.  This version
  8. ;    is intended to run on the DSP56000ADSx (Application Development
  9. ;    System) board rev #2, with memory expansion.  The memory should 
  10. ;    be configured figured for 8K p-memory, 16K x-memory, 8K y-memory.
  11. ;    
  12. ;    Further gains in algorithm speed could be realized on boards not
  13. ;    constrained by the ADS memory limitations.  For example, due to
  14. ;    the need for 4 comb filters' worth of storage (each using about 
  15. ;    3500 samples - which takes 4096 samples each after using the DSM
  16. ;    statement) to fit into the 16K available for the x memory, we
  17. ;    must start at address $0000.  Thus, we are forced to use all the
  18. ;    56000's internal memory for sample storage.  Without being forced
  19. ;    to start sample storage at $0000, the 56000's internal memory could
  20. ;    be used for coefficient storage, allowing better use of parallel 
  21. ;    x and y moves.
  22. ;
  23. ;                Motorola DSP Group
  24. ;                Austin, Texas
  25. ;
  26. ;**************************************************************************
  27. ; This program was originally available on the Motorola DSP bulletin board
  28. ; and is provided under a DISCLAIMER OF WARRANTY available from Motorola
  29. ; DSP Operation, 6501 William Cannon Dr. W Austin, Texas  78735-8598.
  30. ;**************************************************************************
  31. ;--------------------------------------------------------------------------
  32. ;    This reverberation program is a variation of the reverberation
  33. ;    system and structures as described by James Moorer's article entitled
  34. ;     'About this Reverberation Business', Computer Music Journal,
  35. ;     3(2):13-28, 1979
  36. ;
  37. ;    Structure is:
  38. ;                            .----------.
  39. ;                 .------------.   .-----.    | All Pass |
  40. ;              +->| Comb Filter|-->| SUM |-->| Reverb   |
  41. ;   Note: All Comb      |  |   #1       |   '-----'    |       |
  42. ;      Filters      |  '------------'   ^  ^  ^    '----------'
  43. ;      Have a 1st      |  .------------.   |  |  |         |
  44. ;      Order IIR       |->| Comb Filter|---+  |  |     .---V---.
  45. ;      LPF in their      |  |   #2       |      |  |     | align |
  46. ;      feedback      |  '------------'      |  |     | delay |
  47. ;      loop          |  .------------.      |  |     '---|---'
  48. ;              |->| Comb Filter|------+  |         |
  49. ;              |  |   #3       |         |       -----   reverb      
  50. ;              |  '------------'         |        \./     gain
  51. ;              |  .------------.         |         |
  52. ;              |->| Comb Filter|---------+         |
  53. ;              |  |   #4       |                  |
  54. ;              |  '------------'             |
  55. ;              |                     V
  56. ;      .------------.  |        FIR gain          .----------.
  57. ;         |   Early    |  |         |\               |          |
  58. ;input -->| Reflection |--+---------|  >------------>|  summer  |--- output
  59. ;      |  |    FIR     |        |/               |          |
  60. ;      |  '------------'                             '----------'      
  61. ;      |                                   ^
  62. ;      |                                   |
  63. ;      |                     dry gain             |
  64. ;      |                  |\                  |
  65. ;      +------------------------------|  >----------------+
  66. ;                      |/
  67. ;    
  68. ;.............................................................................
  69. ;  COMB FILTER SUB STRUCTURE:
  70. ;                 .-------.
  71. ;      comb i        .-----.     | long  |               comb i
  72. ;      input  ------>| sum |---->| delay |-------+--------->  output
  73. ;             '-----'     '-------'     |
  74. ;            ^                 |
  75. ;            |               V
  76. ;            |       /|           .-----.
  77. ;            +-----<   ------------| sum |<--------+
  78. ;                \|          '-----'          |
  79. ;                 fdbck i         |         / \  lpf i gain
  80. ;                  gain         V       /_____\
  81. ;                  gain           .----------.     |
  82. ;                         | 1 sample |     |
  83. ;                         |    delay    |-----+
  84. ;                         '----------'
  85. ;.............................................................................
  86. ;   UNIT (ALL PASS) REVERBERATOR STRUCTURE:
  87. ;   based on Schroeder as outlined in Griesinger: 'Practical Processors and
  88. ;   Programs for Digital Reverberation', Audio in Digital Times, 7th AES
  89. ;   conference, Toronto, Ontario, 1989
  90. ;   (the structure outlined in Moorer is a variation of this)
  91. ;
  92. ;                       -g
  93. ;                 |\
  94. ;         +---------->|  >--------------------------+
  95. ;         |         |/                   |
  96. ;         |                       |
  97. ;         |                       V
  98. ;    unit     |    .-----.   .--------.       |\     .-----.          unit
  99. ;    input ------+--->| sum |-->| delay  |--+--->|  >-->| sum |-----> output
  100. ;              '-----'   '--------'  |    |/     '-----'
  101. ;             ^            |    1-g**2
  102. ;             |     g        | 
  103. ;             |       /|        |
  104. ;             +-----<  |---------+
  105. ;                     \|
  106. ;
  107. ;...........................................................................
  108. ;
  109. ;    one multi-tap fir structure - to handle early reflections
  110. ;
  111. ;    followed by 4 parallel comb (iir) filters (each comb having 
  112. ;    a first order LPF in its feedback loop
  113. ;    
  114. ;    followed by an 'allpass' reverberator whose output is then 
  115. ;    delayed so that its first output follows after the last "early
  116. ;    reflection" output 
  117. ;
  118. ;__________________________________________________________________________
  119. ;
  120.     opt cex
  121.     page 132
  122.  
  123. ;--------------------------------------------------constant declarations
  124. adc    equ    $ffef        ; ADC address
  125. dac    equ    $ffef        ; DAC address
  126.  
  127. ntap    equ    7        ; number of taps 
  128. ntapp10 equ    ntap+10        ; # taps + 10 for other variables
  129. tapmod    equ    ntapp10-1    ; number of taps minus 1     
  130. dlymx     equ    4000        ; length of delay line in samples
  131.  
  132. cmbdly1 equ    2205        ; COMB FILTER CONSTANTS
  133. cmbdly2 equ    2690        ; delay values (in samples)
  134. cmbdly3 equ    3175
  135. cmbdly4 equ    3440
  136.  
  137. cmbmod1 equ      3490             ; modulo for comb #1 delay line   THESE ARE
  138. cmbmod2 equ      3490         ;   "         "   #2   "   "      ALSO THE 
  139. cmbmod3    equ      3490         ;   "         "   #3  "    "      MAX DELAYS
  140. cmbmod4    equ      3490         ;   "         "   #4  "    "      ALLOWED FOR
  141.                 ;                  CHOSEN DSM
  142.                 ;                  VALUE
  143.  
  144. untrvbdly    equ    265            ; delay    UNIT (or ALLPASS)
  145. unt_g             equ    0.7            ; gains (g)    REVERBERATOR
  146. neg_g        equ    -unt_g            ;        (-g)
  147. one_m_g2    equ    (1-unt_g*unt_g)        ;    "   (1-g**2)
  148.  
  149.  
  150. cmb_g        equ    0.86        ; (OVERALL) COMB FILTER FEEDBACK GAIN 
  151.                     ; controls reverb decay time: smaller
  152.                     ; values give quicker decay, larger
  153.                     ; values yield slower decay
  154.  
  155. lpf1        equ    0.408        ; lpf filter coefficient in the 
  156. lpf2        equ    0.448        ; feedback loop of the combs,
  157. lpf3        equ    0.476        ; these LPF's simulate the high freq
  158. lpf4        equ    0.496        ; attentuation in real acoustic reverb
  159.  
  160. fdbck1        equ    cmb_g*(1-lpf1)    ; actual comb feedback gain
  161. fdbck2        equ    cmb_g*(1-lpf2)    ; is determined by the lpf filter
  162. fdbck3        equ    cmb_g*(1-lpf3)    ; coefficient and the overall feed-
  163. fdbck4        equ    cmb_g*(1-lpf4)    ; back gain to insure stability
  164.  
  165.  
  166. aligndly        equ    1305       ; alignment delay (see diagram above)
  167. alignmod        equ    1390    ;     "     mod
  168.  
  169.     
  170. reverbg        equ    0.35        ; reverberation output gain value
  171. firg        equ    0.15        ; early rflctn FIR output gain value
  172. dryg        equ    0.9999-(reverbg+firg) ; dry signal gain is rest  
  173.                     ; CHOOSE THE MIX YOU LIKE
  174.  
  175.  
  176.     org x:0
  177. chead1    dsm 3500        ; allocates 3500 data spaces for use as
  178. chead2    dsm 3500        ; comb filter tap delay lines, CHEAD1 refers
  179. chead3    dsm 3500        ; to the Comb filter HEAD (beginning) for 
  180. chead4    dsm 3500        ; filter #1  
  181.  
  182.     org x:$0f00
  183. ofst_bf    dsm    ntapp10        ; this reserves "ntap" contiguous addresses
  184.     org x:ofst_bf        ; starting at the closest appropriate modulo
  185. ofst0    dc    1        ; x address space.  Then starts filling the 
  186. ofst1    dc    877        ; offset buffer at this location with   
  187. ofst2    dc    1561        ; the right delay values for the 
  188. ofst3    dc    1716        ; EARLY REFLECTION FIR
  189. ofst4    dc    1826
  190. ofst5    dc    3083      ; IMPORTANT - to get no delay for the first 
  191. ofst6   dc    3510      ; early reflection, use a "1".  This is due the use
  192.               ; of an instruction code pre-decrement, a "0" value 
  193.               ; will cause a maximum delay equal to the tap delay
  194.               ; line length
  195.  
  196. untdly    dc    untrvbdly    ; define the UNIT REVERBERATOR delay
  197. untmod    dc    untrvbdly-1    ; modulo for    "         "
  198.  
  199. algndly    dc    aligndly
  200. algnmod    dc    alignmod
  201.  
  202.     org y:$0f00
  203. gain_bf dsm ntapp10
  204.     org y:gain_bf        ; starting at y address zero this reserves
  205.                 ; "ntap" contiguous addresses then starts
  206.                 ; filling these addresses with the desired
  207. gain0    dc    0.213        ; tap "gain" values for EARLY REFLECTION FIR
  208. gain1    dc    0.217        ; recommended by moorer
  209. gain2    dc    0.174        ;
  210. gain3    dc    0.135        ; it is recommended to keep many early 
  211. gain4    dc    0.153        ; reflection returns, as these are fed into
  212. gain5    dc    0.157        ; comb filters, than can contribute greatly
  213. gain6    dc    0.051        ; to the later impulse response density
  214. c1g2    dc    fdbck1
  215. c2g2    dc    fdbck2
  216. c3g2    dc    fdbck3
  217. c4g2    dc    fdbck4
  218. c1out    ds    1
  219. untg2    dc    neg_g
  220. untg3    dc    one_m_g2
  221. untg1    dc    unt_g
  222. firgain    dc    firg
  223. drygain    dc    dryg
  224. rvbgain    dc    reverbg
  225.  
  226.     org y:0
  227. c1g1    dc    lpf1        ; comb #1 g1 (LPF gain)
  228. c2g1    dc    lpf2        ;      #2      
  229. c3g1    dc    lpf3        ;      #3
  230. c4g1    dc    lpf4         ;      #4
  231.  
  232.  
  233. sample     ds 1            ; input sample storage address
  234. firout   ds 1            ; early ref FIR OUTput storage address
  235.  
  236.                 ; COMB filter    output storage address
  237. c2out  ds 1            ;  "      "   #2   "       "       "
  238.  
  239. lpfst1    ds 1            ;  "      "   #1 Low Pass Filter state
  240. lpfst2    ds 1            ;  "      "   #2  "    "    "      "
  241. lpfst3  ds 1            ;  "      "   #3  "    "    "      "
  242. lpfst4    ds 1            ;  "      "   #4  "    "    "      "
  243.  
  244.                 ; allocates modulo memory for the unit
  245. udlyln    dsm    300        ; (allpass) reverberator delay line 
  246.  
  247. algndlyln dsm    1400        ; allocates modulo memory for alignment delay  
  248.                 ; line
  249.  
  250. dlyline    dsm dlymx        ; allocates mod memory for the FIR delay line
  251.  
  252. ;--------------------------------------------------------------------------
  253.      org     p:$40        ; program start address
  254.  
  255. ; Set up ADS board in case of force break instead of force reset
  256.        movep #0,x:$FFFE         ;set bcr to zero
  257.        movec #0,sp              ;init stack pointer
  258.        movec #0,sr              ;clear loop flag
  259.  
  260. ; Set up the SSI for operation with the DSP56ADC16EVB
  261. ; The following code sets port C to function as SCI/SSI
  262.        move #$0,a0              ;zero PCC to cycle it
  263.        movep a0,x:$FFE1
  264.        move #$0001ff,a0
  265.        movep a0,x:$FFE1         ;write PCC
  266.  
  267. ; The following code sets the SSI CRA and CRB control registers for external
  268. ; continuous clock, synchronous, normal mode.
  269.        move #$004000,a0         ;CRA pattern for word length=16 bits
  270.        movep a0,x:$FFEC
  271.        move #$003200,a0    ;CRB pattern for continous ck,sych,normal mode
  272.        movep a0,x:$FFED    ;word long frame sync: FSL=0;ext ck/fs 
  273.  
  274. ; -------------------------------------------------------------------------
  275.                 ; initialize registers MO,RO, etc
  276.     move #dlymx-1,m0    ; tap line modulus
  277.     move #dlyline,r0     ; start of delay line
  278.     move #0,n0         ; 
  279.  
  280.     move #tapmod,m1        ; tap gain line modulo
  281.     move #gain_bf,r1     ; tap gain & tap delay pointer
  282.  
  283.     move #cmbmod1,m2    ; initialize the modulo registers
  284.     move #cmbmod2,m3    ; for comb filter buffers 1 thru 5
  285.     move #cmbmod3,m4
  286.     move #cmbmod4,m5
  287.  
  288.     move #cmbdly1,n2    ; initialize the offset register
  289.     move #cmbdly2,n3    ; for Comb filters 1 thru 5
  290.     move #cmbdly3,n4
  291.     move #cmbdly4,n5
  292.  
  293.     move #chead1,r2        ; initialize the pointer values for
  294.     move #chead2,r3        ; Comb filters 1 thru 5
  295.     move #chead3,r4
  296.     move #chead4,r5
  297.  
  298.     move x:algnmod,m6    ; initialize alignment delay line
  299.     move x:algndly,n6    ; offset, modulo, and pointer registers
  300.     move #algndlyln,r6
  301.  
  302.     move x:untmod,m7    ; initialize unit reverberator (allpass)
  303.     move x:untdly,n7    ; offset, modulo, and pointer registers
  304.     move #udlyln,r7
  305.  
  306. ;---------------------------------------------------------------------------
  307. ; The following code polls the RDF flag in the SSI-SR and waits for RDF=1
  308. ; and then reads the RX register to retrieve the data from the A/D converter.
  309. ; Sample rate is controlled by DSP56ADC16 board.   
  310.  
  311. poll    jclr #7,x:$FFEE,poll     ;loop until RDF bit = 1
  312.         movep x:adc,a            ;get A/D converter data
  313. ;---------------------------------------------------------------------------
  314.     asr a
  315.     asr a            ; obtain data sample 
  316.                 ; and shift right for headroom
  317.     move a,y:sample        ; keep dry sample
  318.  
  319. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  320. ; FIR for early reflections
  321.     move a,y:(r0)-        ; push sample into delay line
  322.     clr a    x:(r1),n0    ; clr A and load offset into N0
  323.     do #ntap,fir         ; loop over the (ntaps-1),exclude fb tap now
  324.        move y:(r1)+,y1    ;  "   "   "   gain   "      "  Y
  325.        move y:(r0+n0),x1    ; get delayed sample
  326.        mac x1,y1,a    x:(r1),n0 ; MAC gain and sample & update offset
  327. fir      move a,y:firout        ; save FIR OUTput to y memory
  328. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  329. ; COMB 1
  330.     move x:(r2+n2),b    ; get delayed sample & put in b
  331.     move b,y:c1out        ; move output to y memory space
  332.  
  333.     move y:c1g1,x1            ; get LPF filter coeff
  334.     move y:lpfst1,y1        ; get LPF filter state
  335.     mac x1,y1,b    y:(r1)+,x1    ; compute LPF output
  336.     move b,y:lpfst1            ; save LPF output to LPF state
  337.  
  338.     move b,y1            ; put LPF output in Y1
  339.     mac x1,y1,a    x:(r3+n3),b    ; compute feedback term in A
  340.     move a,x:(r2)-            ; store output into delay queue
  341.  
  342. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  343. ; COMB 2
  344.     move y:firout,a        ; comb filter #1 with LPF in feed back
  345.     move b,y:c2out        ; move output to y memory space
  346.  
  347.     move y:c2g1,x1            ; get LPF filter coeff
  348.     move y:lpfst2,y1        ; get LPF filter state
  349.     mac x1,y1,b    y:(r1)+,x1    ; compute LPF output
  350.     move b,y:lpfst2            ; save LPF output to LPF state
  351.  
  352.     move b,y1            ; put LPF output in Y1
  353.     mac x1,y1,a    x:(r4+n4),b    ; compute feedback term in A
  354.     move a,x:(r3)-            ; store output into delay queue
  355.  
  356. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  357. ; COMB 3
  358.     move y:firout,a        ; comb filter #1 with LPF in feed back
  359.     move b,x0
  360.  
  361.     move y:c3g1,x1            ; get LPF filter coeff
  362.     move y:lpfst3,y1        ; get LPF filter state
  363.     mac x1,y1,b    y:(r1)+,x1    ; compute LPF output
  364.     move b,y:lpfst3            ; save LPF output to LPF state
  365.  
  366.     move b,y1            ; put LPF output in Y1
  367.     mac x1,y1,a    x:(r5+n5),b    ; compute feedback term in A
  368.     move a,x:(r4)-            ; store output into delay queue
  369. ;  -  -  -  -  -  -   -    -    -    -   -   -   -    -   -     -   - 
  370. ; COMB 4
  371.     move y:firout,a        ; 
  372.     move b,y0
  373.  
  374.     move y:c4g1,x1            ; get LPF filter coeff
  375.     move y:lpfst4,y1        ; get LPF filter state
  376.     mac x1,y1,b    y:(r1)+,x1    ; compute LPF output
  377.     move b,y:lpfst4            ; save LPF output to LPF state
  378.  
  379.     move b,y1            ; put LPF output in Y1
  380.     mac x1,y1,a    y:(r1)+,x1    ; compute feedback term in A,c1out to x1
  381.     move a,x:(r5)-            ; store output into delay queue
  382. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  383.     move y:c2out,a        ; add output of add four combs
  384.     add x1,a               ;  c2out + c1out
  385.     add x0,a    y:(r7+n7),x0       ; +c3out
  386.     add y0,a    y:(r1)+,y1       ; +c4out
  387.  
  388. ;    asr a    
  389. ;  -  -  -  -  -  -  -  -  -   -   -      -   -    -   -  -  -    -  
  390. ;                 all pass unit reverberator                
  391.     move a,x1
  392.     mpy x1,y1,b    y:(r1)+,y1
  393.  
  394.     mac x0,y1,b    y:(r1)+,y1    ; MAC into b for output (B CONTAINS OUTPUT)
  395.     move b,y:(r6)-
  396.  
  397.     mac x1,y1,a    y:(r6+n6),y1
  398.     move a,y:(r7)-        ; put new+g*delayed into delay line/inc r7
  399. ;  -    -     -     -     -     -     -     -     -     -     -      -     -
  400.     move y:rvbgain,y0
  401.     mpy y1,y0,a    y:(r1)+,x1
  402.  
  403.     move y:firout,y1
  404.     mac x1,y1,a    y:(r1)+,x1
  405.  
  406.     move y:sample,y1    ; mix in the dry sample
  407.     mac x1,y1,a        ; A now contains the output sample
  408.     asr a
  409. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  410. ; Write DSP56ADC16 A/D converter data to the PCM-56
  411.  
  412.            move a,x:dac          ;write the PCM-56 D/A via SSI xmt reg.
  413.            jmp poll                ;loop indefinitely
  414.  
  415.            end
  416. ə     
  417. ə